package ru.ifmo.mlarinsky.classificator.io;

import java.io.File;
import java.io.FilenameFilter;
import java.util.*;

import ru.ifmo.mlarinsky.classificator.model.*;
import ru.ifmo.mlarinsky.classificator.parsing.Parser;

/**
 *
 * @author Михаил
 */
public class InstrumentLoader {
    public static final List<Instrument> SAMPLE_INSTRUMENTS =
            loadInstruments(IOUtil.FIVE_YEARS_INSTRUMENTS_DATA_FILE_PATH, Period.DEFAULT);
    public static final List<Instrument> DJ_INDEXES =
            loadInstruments(IOUtil.INDEXES_DATA_FILE_PATH, Period.DEFAULT);
    public static final List<Instrument> SP_INDEXES =
            loadInstruments(IOUtil.SP_INDEXES_FILE_PATH, Period.DEFAULT);
    public static final String TEST_SYMBOL_IBM = "ibm_test";
    public static final String TEST_SYMBOL_DJ = "djusen_test";
    public static final String TEST_SYMBOL_IBM_PATH =
            IOUtil.TEST_INSTRUMENTS_DATA_FILE_PATH + TEST_SYMBOL_IBM + ".csv";
    public static final String TEST_SYMBOL_DJ_PATH =
            IOUtil.TEST_INSTRUMENTS_DATA_FILE_PATH + TEST_SYMBOL_DJ + ".csv";

    private InstrumentLoader() {
    }

    public static List<Instrument> loadInstruments(String dataFilePath, Period period) {
        List<Instrument> instruments = new ArrayList<Instrument>();

        String[] fileList = getInstrumentDataFileList(dataFilePath);

        for (String quoteDataFile : fileList) {
            String symbol = quoteDataFile.replaceAll(".csv", "").toUpperCase();

            instruments.add(loadInstrument(symbol, dataFilePath + quoteDataFile, period));
        }

        return instruments;
    }

    public static Instrument loadInstrument(String symbol, String dataFilePath, Period period) {
        Period periodCopy = new Period(period);
        SortedMap<QuoteDate, Quote> quoteData = new TreeMap<QuoteDate, Quote>();

        List<String> fileStrings = IOUtil.read(dataFilePath);
        for (String string : fileStrings) {
            Quote quote = Parser.parseDataString(symbol, string);
            QuoteDate date = quote.getDate();

            if (periodCopy.accept(date))
                quoteData.put(date, quote);
        }

        Instrument instrument = new Instrument(symbol, quoteData);
        InstrumentRegister.addInstrument(instrument);

        return instrument;
    }

    public static String[] getInstrumentSymbols(String categoryPath) {
        String[] fileList = getInstrumentDataFileList(categoryPath);
        String[] symbols = new String[fileList.length];

        for (int i = 0, length = fileList.length; i < length; i++)
            symbols[i] = fileList[i].replaceAll(".csv", "").toUpperCase();

        return symbols;
    }

    private static String[] getInstrumentDataFileList(String categoryPath) {
        final File file = new File(categoryPath);
        String[] fileList = {file.getName()};

        if (file.isDirectory()) {
            fileList = file.list(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return dir.equals(file) && name.endsWith(".csv");
                }
            });
        }

        return fileList;
    }

    public static class Period {
        public final static Period DEFAULT = new Period(252, QuoteDate.valueOf("01/01/2011"));
        private final Date from;
        private int length;

        public Period(Period period) {
            this(period.length, period.from);
        }

        public Period(int length, Date from) {
            this.length = length;
            this.from = from;
        }

        public boolean accept(Date date) {
            return date.getTime() >= from.getTime() && --length >= 0;
        }

        public int getLength() {
            return length;
        }

        public Date getStart() {
            return from;
        }
    }
}
